import java.util.List;

import partitions.Partition;

import coalitions.Core;
import coalitions.MergeProof;
import coalitions.NoTreat;
import coalitions.SplitProof;
import externality.Externality;


public class AltruismFixture implements Externality{
	
	public static void main(String[] args) {
		AltruismFixture altruismFixture = new AltruismFixture();
		
		
		System.out.println("Core partitions");
		
		Core core = new Core(altruismFixture);
		List<int[]> corePartitions = core.getCore();
		for(int[] partition : corePartitions){
			System.out.println(Partition.partitionToExpandedString(partition));
		}
		
		System.out.println("________________________________________________________");
		System.out.println("Split-proof partitions");
		
		SplitProof splitProof = new SplitProof(altruismFixture);
		List<int[]> splitProofPartitions = splitProof.getSplitProofPartitions();
		for(int[] partition : splitProofPartitions){
			System.out.println(Partition.partitionToExpandedString(partition));
		}		
		System.out.println("________________________________________________________");
		System.out.println("Merge-proof partitions");
		
		MergeProof mergeProof = new MergeProof(altruismFixture);
		List<int[]> mergeProofPartitions = mergeProof.getMergeProofPartitions();
		for(int[] partition : mergeProofPartitions){
			System.out.println(Partition.partitionToExpandedString(partition));
		}			
		
		System.out.println("________________________________________________________");
		System.out.println("No-treat partitions");
		
		NoTreat noTreat = new NoTreat(altruismFixture);
		List<int[]> noTreatPartitions = noTreat.getNoTreatPartitions();
		for(int[] partition : noTreatPartitions){
			System.out.println(Partition.partitionToExpandedString(partition));
		}					
		
	}
	
	public AltruismFixture(){
		
	}
	
	@Override
	public float[] getExternalities(int[] partition) {
		if(intArrayEquals(partition, new int[]{0, 0, 0}))
			return new float[]{9, 9, 12};
		else if(intArrayEquals(partition, new int[]{0, 0, 1}))
			return new float[]{10, 10, 7};
		else if(intArrayEquals(partition, new int[]{0, 1, 0}))
			//return new int[]{1, 0, 13};	//no core
			return new float[]{13, 0, 13};		//a core
		else if(intArrayEquals(partition, new int[]{0, 1, 1}))
			return new float[]{0, 10, 12};
		else if(intArrayEquals(partition, new int[]{0, 1, 2}))
			return new float[]{13, 9, 11};
		else {
			System.out.println(utils.Util.printIntArray(partition));
			throw new IllegalArgumentException("invalid partition specification");
		}
	}
	
	boolean intArrayEquals(int[] a, int[] b) {

		if (a == null || b == null)
			throw new IllegalArgumentException("can't compare null arrays");
		
	    if (a.length != b.length)
	        throw new IllegalArgumentException("can't compare unequal arrays");

	    for (int i = 0; i < a.length; i++) {
	        if (a[i] != b[i])
	            return false;
	    }
	    return true;
	}

	@Override
	public int getSize() {
		return 3;
	}
	
	

}
